﻿using System;
using System.Collections.Generic;
using Atmk.WaterMeter.MIS.Commons.Interfaces.GateWay;
using Atmk.WaterMeter.MIS.Commons.Utils;
using Atmk.WaterMeter.MIS.Entities;
using Atmk.WaterMeter.MIS.Entities.Enums;
using Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.ViewModel;
using Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.ViewModel.DeviceCommands;
using Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.ViewModel.Enums;
using Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.ViewModel.GateWay;
using Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.ViewModel.NaRespon;
using Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.ViewModel.RequestParam;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;

namespace Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.Logic
{
    public class CT_NBIoT_CommandSenderHelper : ICT_NBIoT_CommandSenderHelper
    {
        private readonly Logger _logger = LogManager.GetCurrentClassLogger();
        private const string CALL_BACK_URL = "https://water-meter-atmk.aixiyou.com:3586/api/CT_Callback/CommandCallback";
        private readonly CT_NBIoT_Visiter _visited;
        private TokenResult _token;

        /// <summary>
        ///     初始化网关
        /// </summary>
        public CT_NBIoT_CommandSenderHelper()
        {
            var platformIp = CT_NBIoT_ConfigParameter.PlatformID;
            var appId = CT_NBIoT_ConfigParameter.AppId;
            var appSecret = CT_NBIoT_ConfigParameter.AppSecret;
            var port = CT_NBIoT_ConfigParameter.Port;
            _visited = new CT_NBIoT_Visiter(appId, appSecret, platformIp, port);
        }

        /// <summary>
        ///     获取抄表数据--数据采集--全部历史数据  注：读取水表数据
        /// </summary>
        /// <param name="deviceId"></param>
        /// <returns></returns>
        public List<MeterReadEntity> ReadDataHistory(string deviceId)
        {
            var deparam = new DeviceHistoryParam
            {
                pageSize = 100,
                deviceId = deviceId,
                gatewayId = deviceId,
                serviceId = ServiceIdEnum.uploadwatermetermsg.ToString()
            };
            if (_token == null)
                _token = _visited.GetToken();
            var historyDatas = _visited.GetDevicesHistory(_token.AccessToken, deparam);
            var result = new List<MeterReadEntity>();
            foreach (var item in historyDatas.deviceDataHistoryDTOs)
            {
                if (item.serviceId != deparam.serviceId)
                    continue;
                var mr = new MeterReadEntity
                {
                    Data = PropertyHelper.SetJobjectePropertyName(new DeviceData(), item.data),
                    DeviceId = deviceId,
                    TimeStamp = item.timestamp
                };
                result.Add(mr);
            }

            return result;
        }

        /// <summary>
        ///     获取电信平台指定设备的所有的冻结数据信息
        /// </summary>
        /// <param name="deviceId"></param>
        /// <returns></returns>
        public List<MeterFreezDataEntity> ReadFreezDatasHistory(string deviceId)
        {
            var deparam = new DeviceHistoryParam
            {
                pageSize = 100,
                deviceId = deviceId,
                gatewayId = deviceId,
                serviceId = ServiceIdEnum.wmfreezedatamsg.ToString()
            };
            if (_token == null)
                _token = _visited.GetToken();
            var historyDatas = _visited.GetDevicesHistory(_token.AccessToken, deparam);
            var result = new List<MeterFreezDataEntity>();
            foreach (var item in historyDatas.deviceDataHistoryDTOs)
            {
                var mf = PropertyHelper.SetJobjectePropertyName(new MeterFreezDataEntity(), item.data);
                mf.deviceId = deviceId;
                mf.timestamp = item.timestamp;
                result.Add(mf);
            }

            return result;
        }

        /// <summary>
        ///     发送获取冻结数据指令
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="frozenType"></param>
        /// <returns></returns>
        public DeviceCommandResp SendFreezingCommand(string deviceId, FrozenType frozenType)
        {
            var commandparas = new CommandFreezeParas
                {
                    freezetype = (int) frozenType,
                    time = DateTime.Now.TimeBase64ToString(),
                    //电信NB北向，不需要endpointid 单因需要NB、Lora协议统一,添加此参数，值设为时间的Base64
                    endpointid = DateTime.Now.TimeBase64ToString()
                }
                ;
            var command = new Command
            {
                method = "wmfreezedatareq",
                serviceId = "wmfreezedatamsg",
                paras = JObject.FromObject(commandparas)
            };
            var pdc = new PostDeviceCommandReq
            {
                deviceId = deviceId,
                callbackUrl = CALL_BACK_URL,
                command = command,
                maxRetransmit = 2
            };
            var dcp = new DeviceCommandsParam();
            if (_token == null)
                _token = _visited.GetToken();
            var result = _visited.PostDeviceCommand(_token.AccessToken, dcp, pdc);
            if (result.StatusCode == 201)
            {
                var resp = JsonConvert.DeserializeObject<DeviceCommandResp>(result.Result);
                return resp;
            }

            throw new Exception($"电信平台反馈错误码{result.StatusCode}");
        }

        /// <summary>
        ///     发送开关阀命令
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="tap"></param>
        /// <returns>返回结果类</returns>
        public DeviceCommandResp SendTapCommand(string deviceId, int tap)
        {
            var commandparas = new CommandValveParas
            {
                operation = tap,
                //TODO:协议部分需要根据锐骐进度修改，时间之前长度是8，现在长度是6 需要核实
                time = "123456", //DateTime.Now.TimeBase64ToString(),
                //电信NB北向，不需要endpointid 单因需要NB、Lora协议统一,添加此参数，值设为时间的Base64
                endpointid = DateTime.Now.TimeBase64ToString()
            };
            var command = new Command
            {
                serviceId = "controlvalveresp",
                method = "controlvalve",
                paras = JObject.FromObject(commandparas)
            };
            var pdc = new PostDeviceCommandReq
            {
                deviceId = deviceId,
                callbackUrl = CALL_BACK_URL,
                command = command,
                maxRetransmit = 2
            };
            var dcp = new DeviceCommandsParam();
            if (_token == null)
                _token = _visited.GetToken();
            var result = _visited.PostDeviceCommand(_token.AccessToken, dcp, pdc);
            if (result.StatusCode == 201)
            {
                var resp = JsonConvert.DeserializeObject<DeviceCommandResp>(result.Result);
                return resp;
            }

            throw new Exception($"电信平台反馈错误码{result.StatusCode}");
        }

        /// <summary>
        ///     读取指令发送状态
        /// </summary>
        /// <param name="deviceid"></param>
        /// <returns></returns>
        public List<CommandResultEntity> ReadCommandStatue(string deviceid = "")
        {
            if (_token == null)
                _token = _visited.GetToken();
            var resp = _visited.GetDeviceCommand(_token.AccessToken, new GetCommandsParam());
            var result = new List<CommandResultEntity>();
            foreach (var item in resp.data)
            {
                var cr = new CommandResultEntity
                {
                    CommandId = item.commandId,
                    CommandStatue = item.status
                };
                result.Add(cr);
            }
            return result;
        }


        /// <summary>
        ///     定时 批量开阀命令
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="tap"></param>
        /// <returns>返回结果类</returns>
        public ApiResult batchTapCommand(string[] CTdeviceIds)
        {
            var commandparas = new CommandValveParas
            {
                operation = 1,
                //TODO:协议部分需要根据锐骐进度修改，时间之前长度是8，现在长度是6 需要核实
                //time = "123456",//DateTime.Now.TimeBase64ToString(),
                time = DateTime.Now.TimeBase64ToString(),
                //电信NB北向，不需要endpointid 单因需要NB、Lora协议统一,添加此参数，值设为时间的Base64
                endpointid = DateTime.Now.TimeBase64ToString()
            };
            var command = new Command
            {
                serviceId = "controlvalveresp",
                method = "controlvalve",
                paras = JObject.FromObject(commandparas)
            };
            var taskparam = new TaskParam
            {
                type = "DeviceList",
                deviceList = CTdeviceIds,
                command = command
            };
            var pdc = new TaskDeviceCommand
            {
                appId = _visited._MAppid,
                timeout = 1500,
                taskName = "TaskTapCommand" + DateTime.Now.ToString("yyMMddhhmm"),
                taskType = "DeviceCmd",
                param = taskparam
            };
            var dcp = new DeviceCommandsParam();
            //if (_token == null)
                _token = _visited.GetToken();
            var result = _visited.PostTaskDeviceCommand(_token.AccessToken, dcp, pdc);
            _logger.Debug("定时开阀返回结果:" + result.StatusCode + result.Result);
            return result;
            //if (result.StatusCode == 200)
            //{
            //var resp = JsonConvert.DeserializeObject<DeviceCommandResp>(result.Result);

            //    return resp;
            //}

            //return new DeviceCommandResp();
            //throw new Exception($"电信平台反馈错误码{result.StatusCode}");
        }
    }
}